/**
 * Created with JetBrains WebStorm.
 * User: Endre Balogh
 * Date: 5/30/13
 * Time: 12:47 PM
 */

'use strict';

angular.module('ender.game.boardgames', [ 'ender.boardgames.tictactoe', 'ender.boardgames.reversi', 'ender.boardgames.junglechess' ])
    .controller('BoardgameController', function ($scope, $routeParams, boardgameService) {
        var currentGame = boardgameService.getCurrentGame();
        if (!currentGame.gameId) {
            boardgameService.reinitCurrentGame($routeParams.boardgameId);
        }
        if (currentGame.gameId !== $routeParams.boardgameId) {
            boardgameService.startBoardGame(currentGame.gameId);
            return;
        }

        $scope.returnUrl = currentGame.returnUrl;

        var game = currentGame.game;
        game.processRules(currentGame.customRules);

        $scope.cellClass = game.getClassForCell();
        $scope.playerIndicatorClass = game.getClassForPlayerIndicator();

        $scope.gameId = $routeParams.boardgameId;
        $scope.gameName = game.name;

        var players = [
            {
                name: "Player"
            },
            {
                name: currentGame.opponentName
            }
        ];
        game.processPlayers(players);
        $scope.players = players;

        $scope.resetBoard = function () {
            var board = createBoard(game.boardSize);
            game.preProcessBoard(board, $scope.players);

            if (game.hasScore)
                game.resetScore(players);

            $scope.board = board;
            $scope.currentPlayerIndex = 0;
            $scope.winner = null;

        };
        $scope.resetBoard();

        $scope.getCurrentPlayer = function () {
            return $scope.players[$scope.currentPlayerIndex];
        }

        $scope.hasScore = game.hasScore;

        $scope.cellClicked = function (row, column) {
            if ($scope.winner)
                return;

            if (!game.isLegalMove($scope.board, row, column, $scope.getCurrentPlayer()))
                return;

            game.processCellClicked($scope.board, row, column, $scope.getCurrentPlayer());
            if (game.movesNeedMultipleTurns && !game.moveHasBeenMade()) {
                return;
            }

            if (game.hasScore)
                game.updateScore($scope.board, $scope.players);

            var victoryResult = game.checkVictory($scope.board, $scope.players, $scope.getCurrentPlayer());
            if (victoryResult) {
                processVictoryResult(victoryResult);
            } else {
                nextPlayer();
                if (game.canBlockPlayer) {
                    if (!game.playerCanMove($scope.board, $scope.getCurrentPlayer())) {
                        nextPlayer();
                        if (!game.playerCanMove($scope.board, $scope.getCurrentPlayer())) {
                            victoryResult = game.evaluateVictory($scope.board, $scope.players, $scope.getCurrentPlayer());
                            processVictoryResult(victoryResult);
                        }
                    }
                }
            }
        };

        $scope.getClassForCell = function (cell) {
            return game.getClassForCell(cell);
        };

        $scope.getContentForCell = function (cell) {
            return game.getContentForCell(cell);
        };

        function processVictoryResult(victoryResult) {
            if (victoryResult === true) {
                $scope.winner = $scope.getCurrentPlayer().name;
                alert("victory for " + $scope.getCurrentPlayer().name);
            } else if (victoryResult === 'draw') {
                alert("draw");
                $scope.winner = 'noone';
            } else if (typeof victoryResult === 'object') {
                $scope.winner = victoryResult.name;
                alert("victory for " + victoryResult.name);
            }
        }

        function nextPlayer() {
            if ($scope.currentPlayerIndex == 0)
                $scope.currentPlayerIndex = 1;
            else
                $scope.currentPlayerIndex = 0;
        };
        function createBoard(boardSize) {
            var height, width;
            if (boardSize.size) {
                height = width = boardSize.size;
            } else {
                height = boardSize.height;
                width = boardSize.width;
            }

            var board = [];
            for (var i = 0; i < height; i++) {
                var row = [];
                for (var j = 0; j < width; j++) {
                    row.push({});
                }
                board.push(row);
            }
            return board;
        };

    })
    .factory('boardgameService', function ($location, ticTacToeGame, reversiGame, jungleChessGame) {

        var games = {
            "tic-tac-toe": ticTacToeGame,
            "reversi": reversiGame,
            "jungle-chess": jungleChessGame
        };

        var currentGame = {};

        function initCurrentGame(gameId, opponentName, ruleValues, returnUrl) {
            currentGame.gameId = gameId;
            currentGame.game = games[gameId];
            currentGame.opponentName = opponentName || "Player 2";
            currentGame.customRules = ruleValues;
            currentGame.returnUrl = returnUrl || "#/town";
        }

        return {
            getCustomRules: function (gameId) {
                return games[gameId].customRules;
            },
            startBoardGame: function (gameId, opponentName, rules, returnUrl) {
                initCurrentGame(gameId, opponentName, rules, returnUrl);
                $location.path('/gambling/boardgames/' + gameId);
            },
            getCurrentGame: function () {
                return currentGame;
            },
            reinitCurrentGame: function (gameId) {
                initCurrentGame(gameId);
            }
        };
    })
    .directive('endBoardgameCustomrule', function ($compile) {

        return {
            restrict: 'E',
            replace: true,
            templateUrl: "templates/boardgame-customrule.html",
            link: function (scope, element, attrs) {
                var rule = scope.rule;
                if (rule.type === 'choice') {
                    element.find('input').remove();

                    var htmlString = '<select id="rule{{$index}}" ng-disabled="!playWithCustomRules" ng-model="rule.value" ng-options="value for value in rule.values"></select>';
                    element.prepend(htmlString);
                    $compile(element.contents())(scope);
                }
                if (rule.type === 'boolean') {
                    element.find('input').remove();
                    var htmlString = '<input id="rule{{$index}}" type="checkbox" ng-disabled="!playWithCustomRules" ng-model="rule.value">';
                    element.prepend(htmlString);
                    $compile(element.contents())(scope);
                }
            }
        }
    })
    .directive('endGameBoardgameCell', function ($compile) {
        return {
            restrict: 'E',
            replace: true,
            template: '<div></div>',
            link: function (scope, element, attrs) {
                element.addClass(scope.cellClass);
                $compile(element)(scope);
            }
        };
    })
    .directive('endGameBoardgamePlayerIndicator', function ($compile) {
        return {
            restrict: 'E',
            replace: true,
            template: '<div class="player-indicator-container"></div>',
            link: function (scope, element, attrs) {
                element.addClass(scope.playerIndicatorClass);
                $compile(element)(scope);
            }
        };
    });
